package com.qyer.search.model.aggregation;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by tangzheng on 16/7/17.
 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class STGInfo {

  @JsonProperty
  private int size;
  @JsonProperty
  private String name;
  @JsonProperty
  private List<Poi> poi;
  @JsonProperty
  private Map<Integer, List<Topic>> topic;
  @JsonProperty
  private List<Country> country;
  @JsonProperty
  private List<VStype> s_type;
  @JsonProperty
  private List<SetOutPlace> abroad;
  @JsonProperty
  private List<City> start_city_id;
  @JsonProperty
  private List<Integer> travel_day = new ArrayList<>();
  @JsonIgnore
  private List<TravelDay> travelDays;

  public void transfer(){
    if(CollectionUtils.isNotEmpty(travelDays)){
      travel_day.clear();
      for(int i = 0; i < travelDays.size(); i++){
        travel_day.add(travelDays.get(i).getDay());
      }
    }
  }

  public void sort(){

    if(CollectionUtils.isNotEmpty(country)){
      Collections.sort(country);
      for(Country cty:country){
        cty.sort();
      }
    }

    if(CollectionUtils.isNotEmpty(travelDays)){
      Collections.sort(travelDays);
    }

    if(CollectionUtils.isNotEmpty(start_city_id)){
      Collections.sort(start_city_id);
    }

    if(CollectionUtils.isNotEmpty(abroad)){
      Collections.sort(abroad);
    }

    if(!CollectionUtils.isEmpty(poi)){
      Collections.sort(poi);
    }
    if(MapUtils.isNotEmpty(topic)){
      Iterator<Map.Entry<Integer, List<Topic>>> it = topic.entrySet().iterator();
      while(it.hasNext()){
        Map.Entry<Integer, List<Topic>> entry = it.next();
        List<Topic> topics = entry.getValue();
        if(CollectionUtils.isNotEmpty(topics))
          Collections.sort(topics);
      }
    }

    if(CollectionUtils.isNotEmpty(s_type)){
      Collections.sort(s_type);
    }
  }

  /*public STGInfo(int size, String name, List<Poi> poi, Map<Integer, List<Topic>> topic,
                 List<Country> country, List<VStype> s_type, List<SetOutPlace> abroad,
                 List<City> start_city_id, List<Integer> travel_day) {
    this.size = size;
    this.name = name;
    this.poi = poi;
    this.topic = topic;
    this.country = country;
    this.s_type = s_type;
    this.abroad = abroad;
    this.start_city_id = start_city_id;
    this.travel_day = travel_day;
  }*/

  public STGInfo() {
  }

  public STGInfo(int size, String name) {
    this.size = size;
    this.name = name;
  }

  public STGInfo(int size, String name, List<Poi> poi, Map<Integer, List<Topic>> topic,
                 List<Country> country, List<VStype> s_type, List<SetOutPlace> abroad,
                 List<City> start_city_id, List<TravelDay> travelDays) {
    this.size = size;
    this.name = name;
    this.poi = poi;
    this.topic = topic;
    this.country = country;
    this.s_type = s_type;
    this.abroad = abroad;
    this.start_city_id = start_city_id;

    this.travelDays = travelDays;
  }

  public void incSize(){
    size++;
  }

  public int getSize() {
    return size;
  }

  public void setSize(int size) {
    this.size = size;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public List<Poi> getPoi() {
    return poi;
  }

  public void setPoi(List<Poi> poi) {
    this.poi = poi;
  }

  public Map<Integer, List<Topic>> getTopic() {
    return topic;
  }

  public void setTopic(Map<Integer, List<Topic>> topic) {
    this.topic = topic;
  }

  public List<Country> getCountry() {
    return country;
  }

  public void setCountry(List<Country> country) {
    this.country = country;
  }

  public List<VStype> getS_type() {
    return s_type;
  }

  public void setS_type(List<VStype> s_type) {
    this.s_type = s_type;
  }

  public List<SetOutPlace> getAbroad() {
    return abroad;
  }

  public void setAbroad(List<SetOutPlace> abroad) {
    this.abroad = abroad;
  }

  public List<City> getStart_city_id() {
    return start_city_id;
  }

  public void setStart_city_id(List<City> start_city_id) {
    this.start_city_id = start_city_id;
  }

  public List<Integer> getTravel_day() {
    return travel_day;
  }

  public void setTravel_day(List<Integer> travel_day) {
    this.travel_day = travel_day;
  }

  public List<TravelDay> getTravelDays() {
    return travelDays;
  }

  public void setTravelDays(List<TravelDay> travelDays) {
    this.travelDays = travelDays;
  }

  @Override public boolean equals(Object o) {
    if (this == o)
      return true;
    if (o == null || getClass() != o.getClass())
      return false;

    STGInfo stgInfo = (STGInfo) o;

    if (size != stgInfo.size)
      return false;
    if (!name.equals(stgInfo.name))
      return false;
    if (!poi.equals(stgInfo.poi))
      return false;
    if (!topic.equals(stgInfo.topic))
      return false;
    if (!country.equals(stgInfo.country))
      return false;
    if (!s_type.equals(stgInfo.s_type))
      return false;
    if (!abroad.equals(stgInfo.abroad))
      return false;
    if (!start_city_id.equals(stgInfo.start_city_id))
      return false;
    return travel_day.equals(stgInfo.travel_day);

  }

  @Override public int hashCode() {
    int result = size;
    result = 31 * result + name.hashCode();
    result = 31 * result + poi.hashCode();
    result = 31 * result + topic.hashCode();
    result = 31 * result + country.hashCode();
    result = 31 * result + s_type.hashCode();
    result = 31 * result + abroad.hashCode();
    result = 31 * result + start_city_id.hashCode();
    result = 31 * result + travel_day.hashCode();
    return result;
  }

  public void add(STGInfo stgInfo){
    if(null != stgInfo){
      if(stgInfo.getSize() == 0){
        return;
      }else {
        this.size += stgInfo.getSize();
        //poi add
        if(CollectionUtils.isNotEmpty(stgInfo.getPoi())){
          if(CollectionUtils.isNotEmpty(this.poi)){
            for(int i = 0; i < poi.size(); i++){
              Poi poi_1 = poi.get(i);
              boolean isNoGet = true;
              for(int j = 0; (j < stgInfo.getPoi().size()&&isNoGet); j++){
                Poi poi_2 = stgInfo.getPoi().get(j);
                if(poi_1.equals(poi_2)){
                  poi_1.add(poi_2);
                  isNoGet = false;
                  stgInfo.getPoi().remove(j);
                }
              }
            }
            if(CollectionUtils.isNotEmpty(stgInfo.getPoi())){
              poi.addAll(stgInfo.getPoi());
            }
          }else {
            this.poi = stgInfo.getPoi();
          }
        }
        //country
        if(CollectionUtils.isNotEmpty(stgInfo.getCountry())){
          if(CollectionUtils.isNotEmpty(this.country)){
            for(int i = 0; i < country.size(); i++){
              Country c_1 = country.get(i);
              boolean isNoGet = true;
              for(int j = 0; (j < stgInfo.getCountry().size()&&isNoGet); j++){
                Country c_2 = stgInfo.getCountry().get(j);
                if(c_1.equals(c_2)){
                  c_1.add(c_2);
                  isNoGet = false;
                  stgInfo.getCountry().remove(j);
                }
              }
            }
            if(CollectionUtils.isNotEmpty(stgInfo.getCountry())){
              country.addAll(stgInfo.getCountry());
            }
          }else {
            this.country = stgInfo.getCountry();
          }
        }
        //start
        if(CollectionUtils.isNotEmpty(stgInfo.getStart_city_id())){
          if(CollectionUtils.isNotEmpty(this.start_city_id)){
            for(int i = 0; i < start_city_id.size(); i++){
              City c_1 = start_city_id.get(i);
              boolean isNoGet = true;
              for(int j = 0; (j < stgInfo.getStart_city_id().size()&&isNoGet); j++){
                City c_2 = stgInfo.getStart_city_id().get(j);
                if(c_1.equals(c_2)){
                  c_1.add(c_2);
                  isNoGet = false;
                  stgInfo.getStart_city_id().remove(j);
                }
              }
            }
            if(CollectionUtils.isNotEmpty(stgInfo.getStart_city_id())){
              start_city_id.addAll(stgInfo.getStart_city_id());
            }
          }else {
            this.start_city_id = stgInfo.getStart_city_id();
          }
        }
        //
        if(CollectionUtils.isNotEmpty(stgInfo.getTravelDays())){
          if(CollectionUtils.isNotEmpty(this.travelDays)){
            for(int i = 0; i < travelDays.size(); i++){
              TravelDay td = travelDays.get(i);
              boolean isNoGet = true;
              for(int j = 0; (j < stgInfo.getTravelDays().size()&&isNoGet); j++){
                TravelDay td2 = stgInfo.getTravelDays().get(j);
                if(td.equals(td2)){
                  td.add(td2);
                  isNoGet = false;
                  stgInfo.getTravelDays().remove(j);
                }
              }
            }
            if(CollectionUtils.isNotEmpty(stgInfo.getTravelDays())){
              travelDays.addAll(stgInfo.getTravelDays());
            }
          }else {
            this.travelDays = stgInfo.getTravelDays();
          }
        }
        //travelday
        //
        if(CollectionUtils.isNotEmpty(stgInfo.getAbroad())){
          if(CollectionUtils.isNotEmpty(this.abroad)){
            for(int i = 0; i < abroad.size(); i++){
              SetOutPlace sop = abroad.get(i);
              boolean isNoGet = true;
              for(int j = 0; (j < stgInfo.getAbroad().size()&&isNoGet); j++){
                SetOutPlace sop2 = stgInfo.getAbroad().get(j);
                if(sop.equals(sop2)){
                  sop.add(sop2);
                  isNoGet = false;
                  stgInfo.getAbroad().remove(j);
                }
              }
            }
            if(CollectionUtils.isNotEmpty(stgInfo.getAbroad())){
              abroad.addAll(stgInfo.getAbroad());
            }
          }else {
            this.abroad = stgInfo.getAbroad();
          }
        }
        /////stype
        if(CollectionUtils.isNotEmpty(stgInfo.getS_type())){
          if(CollectionUtils.isNotEmpty(this.s_type)){
            for(int i = 0; i < s_type.size(); i++){
              VStype vst = s_type.get(i);
              boolean isNoGet = true;
              for(int j = 0; (j < stgInfo.getS_type().size()&&isNoGet); j++){
                VStype vst2 = stgInfo.getS_type().get(j);
                if(vst.equals(vst2)){
                  vst.add(vst2);
                  isNoGet = false;
                  stgInfo.getS_type().remove(j);
                }
              }
            }
            if(CollectionUtils.isNotEmpty(stgInfo.getS_type())){
              s_type.addAll(stgInfo.getS_type());
            }
          }else {
            this.s_type = stgInfo.getS_type();
          }
        }
        ////topic
        if(stgInfo.getTopic() !=  null){
          if(topic != null){
            Iterator<Map.Entry<Integer, List<Topic>>> it = topic.entrySet().iterator();
            while(it.hasNext()){
              Map.Entry<Integer, List<Topic>> entry = it.next();
              int a = entry.getKey();
              if(stgInfo.getTopic().containsKey(a)){
                List<Topic> topics = stgInfo.getTopic().get(a);
                stgInfo.getTopic().remove(a);
                List<Topic> topicList = entry.getValue();
                //循环
                for(int i = 0; i < topicList.size(); i++){
                  Topic t1 = topicList.get(i);
                  boolean isNoGet = true;
                  for(int j = 0; (j < topics.size()&&isNoGet); j++){
                    Topic t2 = topics.get(j);
                    if(t1.equals(t2)){
                      t1.add(t2);
                      isNoGet = false;
                      topics.remove(j);
                    }
                  }
                }
                if(CollectionUtils.isNotEmpty(topics)){
                  topicList.addAll(topics);
                }
              }
            }
            if(stgInfo.getTopic() != null){
              topic.putAll(stgInfo.getTopic());
            }
          }else {
            topic = stgInfo.getTopic();
          }
        }


      }
    }
  }

}
